package com.ruoyi.loginAndregist.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.Global;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.loginAndregist.domain.*;
import com.ruoyi.loginAndregist.service.ISxzhrcShenheService2;
import com.ruoyi.loginAndregist.service.IWxOpinionService2;
import com.ruoyi.loginAndregist.service.IWxUserService2;
import com.ruoyi.loginAndregist.utils.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileNotFoundException;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.text.SimpleDateFormat;
import java.util.*;

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.core.controller.BaseController;

@Controller
@RequestMapping("/wx_user")
public class WeChartController extends BaseController {

    @Autowired
    private IWxUserService2 wxUserService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private SmsUtil smsUtil;

    @Autowired
    private IWxOpinionService2 wxOpinionService;

    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private ISxzhrcShenheService2 sxzhrcShenheService;



    //授权
    @GetMapping("/grant")
    @ResponseBody
    public ReturnVo loginwechart(@RequestParam(value = "WxCode") String WxCode)  {
        //@RequestParam(value = "WxCode") String WxCode
        ReturnVo returnVo = new ReturnVo();
        //请求微信api获取用户的openid和sessionKey
     //   JSONObject jsonObject = getUserWXLoginInfo(loginDto.getWxCode());
        System.out.println(WxCode);
        JSONObject jsonObject = null;
        try {
            jsonObject = getUserWXLoginInfo(WxCode);
            returnVo.setMsg("成功");
            returnVo.setData(jsonObject);
            returnVo.setStatus("200");
        } catch (Exception e) {
            returnVo.setMsg("服务器错误");
            returnVo.setData(jsonObject);
            returnVo.setStatus("500");
        }
        String openid = (String)jsonObject.get("openid");
        String sessionKey = (String)jsonObject.get("session_key");

        System.out.println(jsonObject);
        return returnVo;   //返回给前端

    }


    //授权
    @PostMapping("/grant1")
    @ResponseBody
    public ReturnVo loginwechart1(@RequestBody String WxCode)  {
        //@RequestParam(value = "WxCode") String WxCode
        ReturnVo returnVo = new ReturnVo();
        //请求微信api获取用户的openid和sessionKey
        //   JSONObject jsonObject = getUserWXLoginInfo(loginDto.getWxCode());
        System.out.println(WxCode);
        JSONObject jsonObject = null;
        try {
            jsonObject = getUserWXLoginInfo(WxCode);
            returnVo.setMsg("成功");
            returnVo.setData(jsonObject);
            returnVo.setStatus("200");
        } catch (Exception e) {
            returnVo.setMsg("服务器错误");
            returnVo.setData(jsonObject);
            returnVo.setStatus("500");
        }
        String openid = (String)jsonObject.get("openid");
        String sessionKey = (String)jsonObject.get("session_key");

        System.out.println(jsonObject);
        return returnVo;   //返回给前端

    }



    //登录
    @ResponseBody
    @PostMapping("/login")
    public ReturnVo login(@RequestBody WxUser2 wxUser2){

        ReturnVo returnVo = new ReturnVo();
        WxUser2 user = null;

        System.out.println(wxUser2);
        List<WxUser2> wxUser2s = wxUserService.selectWxUserList(wxUser2);
        if (wxUser2s ==null|| wxUser2s.size()==0){  //数据库中没有用户信息，插入微信的基本信息
               wxUser2.setMember(0);
               wxUserService.insertWxUser(wxUser2);
               user= wxUser2;
        }else{
            //如果有，查询是不是人才返回用户
            user = wxUser2s.get(0);
        }

        returnVo.setMsg("登录成功");
        returnVo.setData(user);
        returnVo.setStatus("200");
        return returnVo;
    }


    //授权登录
    @ResponseBody
    @PostMapping("/grantLogin")
    public ReturnVo grantLogin(@RequestBody WxUser2 wxUser){




        ReturnVo returnVo = new ReturnVo();


        System.out.println(wxUser.getWxCode());

        WxUser2 user = null;
        if (wxUser ==null){   //
            returnVo.setMsg("请输入正确信息");
            returnVo.setStatus("200");
            return returnVo;
        }
        String wxCode = wxUser.getWxCode();
        System.out.println(wxCode);
        JSONObject jsonObject = null;
        try {
            jsonObject = getUserWXLoginInfo(wxCode);  //发送请求
            String openid = (String)jsonObject.get("openid");
            String sessionKey = (String)jsonObject.get("session_key");

            System.out.println(jsonObject);
            System.out.println("openid"+openid);

            if(openid==null||sessionKey==null){   //请求无结果
                returnVo.setMsg("信息错误");
                returnVo.setStatus("301"); //警告
                return returnVo;
            }
            WxUser2 wxUser2 = wxUserService.selectWxUserByOpenId(openid);  //根据openid查询数据库有没有


            if (wxUser2 ==null&&openid!=null){  //数据库中没有用户信息，插入微信的基本信息
                wxUser.setShenhe(0);  //初始未审核
                wxUser.setMember(0);   //初始不是会员
                wxUser.setOpendid(openid);
                wxUser.setSessionKey(sessionKey);

                wxUser.setCreateTime(DateUtils.getNowDate());
                /*String lngAndLat = LngAndLatUtil.getLngAndLat(wxUser.getLgt(), wxUser.getLat()); //获取位置
                wxUser.setWxUserlocation(lngAndLat);*/


                int i = wxUserService.insertWxUser(wxUser);

                user= wxUser;
            }else{
                //如果有，查询是不是人才，有没有审核返回用户
                user = wxUser2;
            }



            returnVo.setMsg("成功");
            returnVo.setData(user);
            returnVo.setStatus("200");
        } catch (Exception e) {
            returnVo.setMsg("服务器错误");
            returnVo.setData(user);
            returnVo.setStatus("500");
        }


        System.out.println(jsonObject);
        return returnVo;   //返回给前端
        
    }





    //查状态
    @ResponseBody
    @PostMapping("/checkShenHe")
    public ReturnVo ckeckShenHe(@RequestBody WxUser2 wxUser2){

        ReturnVo returnVo = new ReturnVo();
        if (wxUser2 ==null||StringUtils.isEmpty(wxUser2.getOpendid())){
            returnVo.setMsg("信息错误");
            returnVo.setStatus("301");
            return returnVo;
        }

        try {
            WxUser2 wxUser21 = wxUserService.selectWxUserByOpenId(wxUser2.getOpendid());
            returnVo.setMsg("查询成功");
            returnVo.setStatus("200");
            /*String lngAndLat = LngAndLatUtil.getLngAndLat(wxUser.getLgt(), wxUser.getLat()); //获取位置
                wxUser1
                .setWxUserlocation(lngAndLat);*/
            returnVo.setData(wxUser21);
            if (wxUser21.getShenhe()==3){   //返回审核未通过状态信息
                List<SxzhrcShenhe2> sxzhrcShenhe2s = sxzhrcShenheService.selectSxzhrcShenheByOpenId(wxUser21.getOpendid());
                Collections.sort(sxzhrcShenhe2s, new Comparator<SxzhrcShenhe2>() {
                    @Override
                    public int compare(SxzhrcShenhe2 o1, SxzhrcShenhe2 o2) {
                        return o2.getCreateTime().compareTo(o1.getCreateTime());
                    }
                });
                returnVo.setMsg(sxzhrcShenhe2s.get(0).getMessage());
            }
            return returnVo;
        } catch (Exception e) {
            returnVo.setMsg("服务器错误");
            returnVo.setStatus("500");
            return returnVo;
        }

    }




    //点击注册会员,添加个人一些信息   去等待管理员后台审核
    @ResponseBody
    @PostMapping("/registMember")
    public ReturnVo registMember(@RequestBody WxUser2 wxUser2){
        ReturnVo returnVo = new ReturnVo();

        System.out.println("wxUser"+ wxUser2);
        WxUser2 wxUser21 = null;
        try {
            wxUser21 = wxUserService.selectWxUserByOpenId(wxUser2.getOpendid());
        } catch (Exception e) {
            returnVo.setMsg("服务器错误");
            returnVo.setStatus("500");
            return returnVo;
        }

        if(wxUser21 ==null){
            returnVo.setMsg("请填写正确信息,发送(openid)");
            returnVo.setStatus("301");
            return returnVo;
        }
        System.out.println("wxUser1"+ wxUser21);

        if(wxUser21.getMember()!=null&& wxUser21.getMember()==1){   //注册之前查询数据库
            returnVo.setMsg("你已经是会员,请勿重复注册");
            returnVo.setData(wxUser21);
            returnVo.setStatus("200");
            return returnVo;
        }

        wxUser2.setShenhe(1);  //审核中
        Integer[] eg = wxUser2.getEg();
        wxUser2.setGraduation(eg[0]);
        wxUser2.setEducation(eg[1]);
        wxUser2.setUpdateTime(DateUtils.getNowDate());
        System.out.println(eg);
        try {
            int i = wxUserService.updateWxUserByOpenId(wxUser2);  //根据openid修改数据到数据库中的用户表

            //插入数据到审核表,作为一次新的提交并记录
            SxzhrcShenhe2 sxzhrcShenhe2 = new SxzhrcShenhe2();
            sxzhrcShenhe2.setOpendid(wxUser2.getOpendid());
            sxzhrcShenhe2.setNewsState(0);
            sxzhrcShenhe2.setCreateTime(DateUtils.getNowDate());
            sxzhrcShenhe2.setUpdateTime(DateUtils.getNowDate());
            int i1 = sxzhrcShenheService.insertSxzhrcShenhe(sxzhrcShenhe2);

            if (i==1&&i1==1){
                returnVo.setMsg("您的信息已提交，待审核");
            }else {
                returnVo.setMsg("提交失败");
            }
            returnVo.setStatus("200");
        } catch (Exception e) {
            returnVo.setMsg("服务器出错,请联系管理员");
            returnVo.setStatus("500");
        }

        returnVo.setData(wxUser2);
        return returnVo;

    }



    //展示个人信息
    @ResponseBody
    @PostMapping("/showMessage")
    public ReturnVo showMessage(@RequestBody WxUser2 wxUser2){

        ReturnVo returnVo = new ReturnVo();
        if (wxUser2 ==null|| wxUser2.getOpendid()==null){
            returnVo.setMsg("请先登录");
            returnVo.setStatus("200");
            return returnVo;
        }

        WxUser2 wxUser21 = wxUserService.selectWxUserByOpenId(wxUser2.getOpendid()); //sessionkey会变，根据openid查用户和
        returnVo.setMsg("查询成功");
        returnVo.setStatus("200");
        returnVo.setData(wxUser21);

        return returnVo;
    }


    //修改个人信息
    @ResponseBody
    @PostMapping("/editSave")
    public ReturnVo updateMessage(@RequestBody WxUser2 wxUser2){

        ReturnVo returnVo = new ReturnVo();
        try {
            wxUser2.setUpdateTime(DateUtils.getNowDate());
            int i = wxUserService.updateWxUserByOpenId(wxUser2);
            if (i==1){
                returnVo.setMsg("修改成功");
            }else{
                returnVo.setMsg("修改失败");
            }
            returnVo.setStatus("200");
        } catch (Exception e) {
            returnVo.setMsg("服务器出错,请联系管理员");
            returnVo.setStatus("500");
        }
        return returnVo;

    }


    //上传图片
    @PostMapping("/editSaveImgUrl")
    @ResponseBody
    public AjaxResult uploadFile(@RequestParam("file")MultipartFile file) throws Exception
    {
        try
        {
            // 上传文件路径
            String filePath = Global.getUploadPath();
            // 上传并返回新文件名称
            String fileName = FileUploadUtils.upload(filePath, file);
            String url = serverConfig.getUrl() + fileName;
            AjaxResult ajax = AjaxResult.success();
            ajax.put("fileName", fileName);
            ajax.put("url", url);
            return ajax;
        }
        catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }


    @PostMapping("/uploadImg")
    @ResponseBody
    public String uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws FileNotFoundException {
        //判断文件是否为空
        if (file.isEmpty()) {
            return "上传文件不可为空";
        }

        // 获取文件名
        String fileName = file.getOriginalFilename();
        fileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) +fileName;

        //放到类路径下的images文件夹中
        String classpath = ResourceUtils.getFile("classpath:").getAbsolutePath();
        String relativePath="/images/"+fileName;
        String path=classpath+relativePath;

        //创建文件路径
        File dest = new File(path);
        //判断文件是否已经存在
        if (dest.exists()) {
            return "文件已经存在";
        }
        //判断文件父目录是否存在
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdir();
        }
        try {
            //上传文件//保存文件
            file.transferTo(dest);
        } catch (Exception e) {
            return "上传失败";
        }
        //服务器路径
        String serverUrl=request.getRequestURL().toString().replace(request.getRequestURI(),"");
        System.out.println(serverUrl+relativePath);
        return serverUrl+relativePath;
    }




    //意见反馈
    @ResponseBody
    @PostMapping("/publicOpnion")
    public ReturnVo publicOpnion(@RequestBody WxOpinion2 wxOpinion2){
        ReturnVo returnVo = new ReturnVo();
       try {
            int i = wxOpinionService.insertWxOpinion(wxOpinion2);
            if (i==1){
                returnVo.setMsg("发表成功");
            }else{
                returnVo.setMsg("发表失败");
            }
            returnVo.setStatus("200");
        } catch (Exception e) {
           returnVo.setMsg("服务器出错,请联系管理员");
           returnVo.setStatus("500");
        }
        return returnVo;
    }



    //解密电话号码
    @ResponseBody
    @PostMapping("/getPhone")
    public ReturnVo getPhoneNumber(@RequestBody DecodeDto decodeDto){

        ReturnVo returnVo = new ReturnVo();

        String encryptedData = decodeDto.getEncryptedData();
        String sessionKey = decodeDto.getSessionKey();
        String iv = decodeDto.getIv();
        if (StringUtils.isEmpty(encryptedData)||StringUtils.isEmpty(sessionKey)||StringUtils.isEmpty(iv)){
            returnVo.setMsg("信息不完全,请重新输入");
            return returnVo;
        }
        // 被加密的数据
        byte[] dataByte = Base64.decode(encryptedData);
        // 加密秘钥
        byte[] keyByte = Base64.decode(sessionKey);
        // 偏移量
        byte[] ivByte = Base64.decode(iv);
        try {
            // 如果密钥不足16位，那么就补足.  这个if 中的内容很重要
            int base = 16;
            if (keyByte.length % base != 0) {
                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                keyByte = temp;
            }
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, "UTF-8");
                returnVo.setData(result);
                return returnVo;

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }



    private JSONObject getUserWXLoginInfo(String WxCode) {
        String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
        Map<String,String> requestUrlParam = new HashMap<String,String>();
       // requestUrlParam.put("appid", "wxd25b30d2edb963ee");	//开发者设置中的appId
        requestUrlParam.put("appid", "wx35698a0e271b3e09");	//开发者设置中的appId
       //requestUrlParam.put("secret", "1db49cc59ad454a32ee80ddb6c2f4959");	//开发者设置中的appSecret
         requestUrlParam.put("secret", "d897fcb1c0f81e6375cdfface829aeb1");	//开发者设置中的appSecret
        requestUrlParam.put("js_code", WxCode);	//小程序调用wx.login返回的code
        requestUrlParam.put("grant_type", "authorization_code");	//默认参数
        //发送post请求读取调用微信 https://api.weixin.qq.com/sns/jscode2session 接口获取openid用户唯一标识
        JSONObject jsonObject = JSON.parseObject(UrlUtil.sendPost(requestUrl, requestUrlParam));
        return jsonObject;
    }


    //后端管理接口,审核之前  人工浏览用户信息
    public ReturnVo checkBefore(@RequestBody WxUser2 wxUser2){
        WxUser2 wxUser21 =null;
        ReturnVo returnVo = new ReturnVo();
        if (wxUser2 ==null){
            returnVo.setMsg("信息有误");
            returnVo.setStatus("301");
            return returnVo;
        }

        try {
           wxUser21 = wxUserService.getWxUser(wxUser2);
        } catch (Exception e) {
            returnVo.setMsg("服务器错误，联系管理员");
            returnVo.setStatus("301");
            return returnVo;
        }
        returnVo.setMsg("查询成功");
        returnVo.setStatus("200");
        returnVo.setData(wxUser21);
        return returnVo;
    }


    //后端管理接口,审核之后  人工浏览用户信息，修改审核状态，如果未通过，填写原因
    @Transactional(rollbackFor = Exception.class)
    public ReturnVo checkLater(SxzhrcShenhe2 shenhe){

        ReturnVo returnVo = new ReturnVo();
        try {
            //插入审核表

            int i = sxzhrcShenheService.insertSxzhrcShenhe(shenhe);

            //修改用户表状态
            WxUser2 wxUser2 = wxUserService.selectWxUserByOpenId(shenhe.getOpendid());
            wxUser2.setShenhe(shenhe.getShenhe());  //修改用户表审核状态
            if (shenhe.getShenhe()!=null&&shenhe.getShenhe()==2){  //审核通过
                wxUser2.setMember(1);
            }
            wxUserService.updateWxUserByOpenId(wxUser2);
            returnVo.setMsg("保存信息成功");
            returnVo.setStatus("200");
        } catch (Exception e) {
            returnVo.setMsg("服务器出小差，请联系管理员");
            returnVo.setStatus("500");
        }
        return  returnVo;

    }


    //发送短信
    public ReturnVo sendSms(@RequestBody SxzhrcShenhe2 shenhe){

        ReturnVo returnVo = new ReturnVo();
        if (shenhe==null||StringUtils.isEmpty(shenhe.getOpendid())){  //判断提交的信息,与Openid
            returnVo.setMsg("提交信息有无,请重新提交.");
            returnVo.setData(shenhe);
            returnVo.setData("301");
            return returnVo;
        }

        WxUser2 wxUser2 = null;
        try {
            wxUser2 = wxUserService.selectWxUserByOpenId(shenhe.getOpendid());
        } catch (Exception e) {
            returnVo.setMsg("服务器出小差了...请联系管理员哦");
            returnVo.setData(shenhe);
            returnVo.setData("500");
            return returnVo;
        }

        //发送短信
        try {
            if (StringUtils.isEmpty(wxUser2.getRealname())){  //如果真实名字为空,用微信昵称
                    if (shenhe.getShenhe().equals(2)){
                        AliyunConfig.sendSms(wxUser2.getWxPhone(), wxUser2.getWxUserName(),"通过");  //审核发送的通过短信
                    }else{
                        AliyunConfig.sendSms(wxUser2.getWxPhone(), wxUser2.getWxUserName(),shenhe.getMessage());  //审核发送的不通过短信
                    }


            }else {
                    if (shenhe.getShenhe().equals(2)){
                        AliyunConfig.sendSms(wxUser2.getWxPhone(), wxUser2.getWxUserName(),"通过");
                    }else{
                        AliyunConfig.sendSms(wxUser2.getWxPhone(), wxUser2.getWxUserName(),shenhe.getMessage());
                    }

            }
        } catch (ClientException e) {
                returnVo.setMsg("服务器出小差了...请联系管理员哦");
                returnVo.setData(shenhe);
                returnVo.setData("500");
        }
        return returnVo;
    }




}
